use crate::uuid;
use serde::{Deserialize, Deserializer};
use std::net::Ipv6Addr;

pub fn be_bytes_try_to_u128(v: &[u8]) -> Result<u128, anyhow::Error> {
    if v.len() != 16 {
        return Err(anyhow::anyhow!("长度错误"));
    }
    let mut arr = [0; 16];
    arr.copy_from_slice(v);
    Ok(u128::from_be_bytes(arr))
}

pub fn be_bytes_try_to_ipv6addr(v: &[u8]) -> Result<Ipv6Addr, anyhow::Error> {
    let v = be_bytes_try_to_u128(v)?;
    Ok(Ipv6Addr::from(v))
}

pub fn now_data_time() -> chrono::DateTime<chrono::Local> {
    chrono::DateTime::<chrono::Local>::from(std::time::SystemTime::now())
}

pub fn now_timestamp_millis() -> u64 {
    now_data_time().timestamp_millis() as u64
}

pub fn new_id() -> Result<String, anyhow::Error> {
    let id = uuid::now_v6()?;
    Ok(id.simple().to_string())
}
pub fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
where
    T: Deserialize<'de>,
    D: Deserializer<'de>,
{
    Deserialize::deserialize(deserializer).map(Some)
}

pub fn slice_try_to<'a, T, R, E>(v: &'a [T]) -> Result<Vec<R>, E>
where
    R: TryFrom<&'a T, Error = E>,
{
    v.into_iter().map(|v| R::try_from(v)).collect()
}
